<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring Bean 并发安全最佳实践</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            line-height: 1.8;
            color: #333;
            background-color: #f9f9f9;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background: #282c34;
            border-radius: 8px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
        }
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 20px rgba(0,0,0,0.08);
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 30px rgba(0,0,0,0.15);
        }
        .method-icon {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            color: white;
            margin-right: 1rem;
        }
        .highlight {
            position: relative;
            padding-left: 1.5rem;
        }
        .highlight:before {
            content: "";
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 4px;
            background: linear-gradient(to bottom, #6e8efb, #a777e3);
            border-radius: 2px;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl md:text-5xl font-bold mb-4">Spring Bean 并发安全</h1>
                    <p class="text-xl opacity-90 mb-8">现代Web应用中的线程安全最佳实践</p>
                    <p class="text-lg opacity-80">在多线程环境中，确保Spring Bean的线程安全性是构建高性能、可靠应用程序的关键。了解这些模式和实践将帮助您避免常见的并发问题。</p>
                </div>
                <div class="md:w-1/2">
                    <div class="mermaid">
                        graph TD
                            A[Spring Bean 并发安全] --> B[避免可变状态]
                            A --> C[线程安全数据结构]
                            A --> D[同步机制]
                            A --> E[局部变量]
                            A --> F[生命周期管理]
                            A --> G[ThreadLocal]
                            A --> H[作用域选择]
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Content Section -->
    <section class="py-16 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl">
            <div class="text-center mb-16">
                <h2 class="text-3xl font-bold mb-4">七种保障Spring Bean线程安全的策略</h2>
                <p class="text-lg text-gray-600 max-w-3xl mx-auto">针对不同的应用场景，选择合适的方式确保您的Spring Bean在多线程环境下安全运行</p>
            </div>

            <!-- Method 1 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-blue-500 to-blue-700">
                        <i class="fas fa-lock"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">1. 避免使用可变状态</h3>
                        <p class="text-gray-600">如果一个Bean的状态是不可变的，那么它就自然是线程安全的。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
public class ImmutableService {
    private final String constantValue = "constant";

    public String getConstantValue() {
        return constantValue;
    }
}</code></pre>
                </div>
                <div class="bg-blue-50 p-4 rounded-lg border border-blue-100">
                    <h4 class="font-bold text-blue-800 mb-2">最佳实践</h4>
                    <p class="text-blue-700">尽可能设计不可变类。将字段声明为final，不提供修改方法。如果必须修改状态，则考虑其他线程安全策略。</p>
                </div>
            </div>

            <!-- Method 2 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-purple-500 to-purple-700">
                        <i class="fas fa-shield-alt"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">2. 使用线程安全的数据结构</h3>
                        <p class="text-gray-600">使用Java并发包中的线程安全集合和原子变量。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
public class SafeCounterService {
    private final AtomicInteger count = new AtomicInteger();

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}</code></pre>
                </div>
                <div class="bg-purple-50 p-4 rounded-lg border border-purple-100">
                    <h4 class="font-bold text-purple-800 mb-2">适用场景</h4>
                    <p class="text-purple-700">计数器、共享集合等场景。Java并发包提供了ConcurrentHashMap、CopyOnWriteArrayList、AtomicInteger等线程安全实现。</p>
                </div>
            </div>

            <!-- Method 3 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-green-500 to-green-700">
                        <i class="fas fa-user-lock"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">3. 同步访问共享资源</h3>
                        <p class="text-gray-600">使用synchronized关键字或显式锁控制对共享资源的访问。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
public class SynchronizedService {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}</code></pre>
                </div>
                <div class="bg-green-50 p-4 rounded-lg border border-green-100">
                    <h4 class="font-bold text-green-800 mb-2">注意事项</h4>
                    <p class="text-green-700">同步会带来性能开销，可能成为瓶颈。只同步必要的代码块，避免过度同步。考虑使用更细粒度的锁机制如ReentrantLock。</p>
                </div>
            </div>

            <!-- Method 4 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-yellow-500 to-yellow-700">
                        <i class="fas fa-code"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">4. 使用局部变量</h3>
                        <p class="text-gray-600">局部变量是线程安全的，因为它们存在于线程的栈中。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
public class LocalVariableService {
    public void process() {
        int localValue = computeValue(); // 局部变量
        // 处理逻辑
    }

    private int computeValue() {
        // 计算逻辑
        return 42;
    }
}</code></pre>
                </div>
                <div class="bg-yellow-50 p-4 rounded-lg border border-yellow-100">
                    <h4 class="font-bold text-yellow-800 mb-2">设计原则</h4>
                    <p class="text-yellow-700">尽可能使用局部变量而不是实例变量。如果方法不需要共享状态，优先使用局部变量，这是最简单有效的线程安全策略。</p>
                </div>
            </div>

            <!-- Method 5 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-red-500 to-red-700">
                        <i class="fas fa-life-ring"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">5. 使用线程安全的 Bean 生命周期管理</h3>
                        <p class="text-gray-600">确保Bean的初始化和销毁过程线程安全。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
public class LifecycleService {
    @PostConstruct
    public void init() {
        // 初始化逻辑，确保线程安全
    }

    @PreDestroy
    public void cleanup() {
        // 清理逻辑，确保线程安全
    }
}</code></pre>
                </div>
                <div class="bg-red-50 p-4 rounded-lg border border-red-100">
                    <h4 class="font-bold text-red-800 mb-2">生命周期安全</h4>
                    <p class="text-red-700">Spring容器会确保@PostConstruct和@PreDestroy方法在适当的时机被调用。在这些方法中访问共享资源时仍需考虑线程安全。</p>
                </div>
            </div>

            <!-- Method 6 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-indigo-500 to-indigo-700">
                        <i class="fas fa-users"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">6. 使用线程局部存储（Thread-Local）</h3>
                        <p class="text-gray-600">ThreadLocal为每个线程提供独立的变量副本。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
public class ThreadLocalService {
    private static final ThreadLocal&lt;Integer&gt; threadLocalValue = 
        ThreadLocal.withInitial(() -> 0);

    public void setValue(int value) {
        threadLocalValue.set(value);
    }

    public int getValue() {
        return threadLocalValue.get();
    }
}</code></pre>
                </div>
                <div class="bg-indigo-50 p-4 rounded-lg border border-indigo-100">
                    <h4 class="font-bold text-indigo-800 mb-2">典型用途</h4>
                    <p class="text-indigo-700">用户会话信息、事务上下文、请求跟踪ID等场景。注意及时清理ThreadLocal变量，避免内存泄漏。</p>
                </div>
            </div>

            <!-- Method 7 -->
            <div class="card bg-white rounded-xl p-8 mb-12 highlight">
                <div class="flex items-start mb-6">
                    <div class="method-icon bg-gradient-to-r from-pink-500 to-pink-700">
                        <i class="fas fa-project-diagram"></i>
                    </div>
                    <div>
                        <h3 class="text-2xl font-bold mb-2">7. 考虑 Bean 的作用域</h3>
                        <p class="text-gray-600">合理选择Bean的作用域可以避免并发问题。</p>
                    </div>
                </div>
                <div class="code-block p-4 mb-6">
                    <pre class="text-gray-300"><code>@Component
@RequestScope
public class RequestScopedService {
    // 每个请求都会创建一个新的实例
}</code></pre>
                </div>
                <div class="bg-pink-50 p-4 rounded-lg border border-pink-100">
                    <h4 class="font-bold text-pink-800 mb-2">作用域策略</h4>
                    <p class="text-pink-700">Spring提供多种作用域：singleton(默认)、prototype、request、session等。根据业务需求选择合适的作用域，避免不必要的共享状态。</p>
                </div>
            </div>

            <!-- Summary -->
            <div class="bg-white rounded-xl p-8 shadow-lg">
                <h3 class="text-2xl font-bold mb-6 text-center">Spring Bean 并发安全策略选择指南</h3>
                <div class="overflow-x-auto">
                    <table class="min-w-full divide-y divide-gray-200">
                        <thead class="bg-gray-50">
                            <tr>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">策略</th>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">适用场景</th>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">性能影响</th>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">复杂度</th>
                            </tr>
                        </thead>
                        <tbody class="bg-white divide-y divide-gray-200">
                            <tr>
                                <td class="px-6 py-4 whitespace-nowrap">避免可变状态</td>
                                <td class="px-6 py-4">状态不变的对象</td>
                                <td class="px-6 py-4">无</td>
                                <td class="px-6 py-4">低</td>
                            </tr>
                            <tr>
                                <td class="px-6 py-4 whitespace-nowrap">线程安全数据结构</td>
                                <td class="px-6 py-4">共享集合、计数器</td>
                                <td class="px-6 py-4">中</td>
                                <td class="px-6 py-4">中</td>
                            </tr>
                            <tr>
                                <td class="px-6 py-4 whitespace-nowrap">同步机制</td>
                                <td class="px-6 py-4">临界区访问</td>
                                <td class="px-6 py-4">高</td>
                                <td class="px-6 py-4">高</td>
                            </tr>
                            <tr>
                                <td class="px-6 py-4 whitespace-nowrap">局部变量</td>
                                <td class="px-6 py-4">方法内状态</td>
                                <td class="px-6 py-4">无</td>
                                <td class="px-6 py-4">低</td>
                            </tr>
                            <tr>
                                <td class="px-6 py-4 whitespace-nowrap">ThreadLocal</td>
                                <td class="px-6 py-4">线程私有数据</td>
                                <td class="px-6 py-4">低</td>
                                <td class="px-6 py-4">中</td>
                            </tr>
                            <tr>
                                <td class="px-6 py-4 whitespace-nowrap">作用域选择</td>
                                <td class="px-6 py-4">减少共享</td>
                                <td class="px-6 py-4">视情况而定</td>
                                <td class="px-6 py-4">中</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </section>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-12">
        <div class="container mx-auto max-w-5xl px-4">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-6 md:mb-0">
                    <h3 class="text-xl font-bold mb-2">技术小馆</h3>
                    <p class="text-gray-400">探索技术之美，分享知识之光</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-blue-300 hover:text-blue-100 transition duration-300">
                        <i class="fas fa-globe mr-2"></i>www.yuque.com/jtostring
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>